package com.mbigger.admin;

import java.nio.charset.StandardCharsets;

import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mbigger.admin.common.ShiroRealm;

@Configuration
public class SpringConfiguration {
	
	/**
	 * 将自己的验证方式加入容器
	 * @return
	 */
	@Bean
	public Realm realm() {
		ShiroRealm realm = new ShiroRealm();
		return realm;
	}
	
	/**
	 * Enabling caching is as simple as providing a CacheManager bean:
	 * @return
	 */
	@Bean
	protected CacheManager cacheManager() {
	    return new MemoryConstrainedCacheManager();
	}
	
	@Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        chainDefinition.addPathDefinition("/login.html", "authc");
        chainDefinition.addPathDefinition("/logout", "logout");
        return chainDefinition;
    }
    
	/**
	 * RestTemplate配置，用来请求远程服务器
	 * 
	 * @return
	 */
	@Bean
	public RestTemplate restTemplate() {
		// 设置apache httpclient为默认的工具，以支持gzip,maven中已手动增加httpclient依赖
		RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
		// 设置中文编码支持，不设置时使用默认编码，会有乱码
		restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
		return restTemplate;
	}

	/**
	 * 设置redisTemplate对象，主要是它的序列化方法，如果存储的key和vlue都是简单字符串，可以直接使用stringRedisTemplate
	 * 
	 * @param factory
	 *            连接工厂
	 * @return bean对象
	 */
	@Bean
	public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
		StringRedisTemplate template = new StringRedisTemplate(factory);
		RedisSerializer<String> strinRedisSerializer = new StringRedisSerializer();
		Jackson2JsonRedisSerializer<String> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<String>(
				String.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		jackson2JsonRedisSerializer.setObjectMapper(om);
		// 如果key是String 需要配置一下StringSerializer,不然key会乱码 /XX/XX
		template.setKeySerializer(strinRedisSerializer);
		template.setValueSerializer(jackson2JsonRedisSerializer);
		template.setHashValueSerializer(jackson2JsonRedisSerializer);
		template.afterPropertiesSet();
		return template;
	}
}
